﻿using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Threading;
using System.Reflection;
using System.ComponentModel;
using Android.Util;

namespace UnitDriven
{
  [Activity(Label = "UnitDriven", MainLauncher = true)]
  public class MainActivity : Activity
  {
    protected TestContext _testContext = null;
    protected Assembly _mainAssembly = null;
    protected ProgressDialog _waitWindow = null;
    protected TestListAdapter _listAdapter = null;

    //Only one of these ever run at once
    protected static MainActivity _activity = null;

    protected override void OnCreate(Bundle bundle)
    {

      // Set our view from the "main" layout resource
      //SetContentView(Resource.Layout.Main);
      base.OnCreate(bundle);

      SetContentView(Resource.Layout.TestEngine);
      
      _activity = this;

      AppDomain.CurrentDomain.UnhandledException += (o, e) => UnhandledException(o, e);
      Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (o, e) => Android_UnhandledException(o, e);

    }

    private void Android_UnhandledException(object sender, RaiseThrowableEventArgs e)
    {
			e.Handled = true;
      Log.Wtf("UnitTestAndroid", e.Exception.ToString());
    }

    private void UnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
      Log.Wtf("UnitTestAndroid", e.ExceptionObject.ToString());
    }    

    private void SummaryButtonClick(object sender, EventArgs e)
    {
      Toast.MakeText(_activity, _testContext.ToSummary().ToString(), ToastLength.Long).Show();
    }

    private void RunAllButtonClick(object sender, EventArgs e)
    {
      try //This shouldn't Generate any errors but one never knows...
      {
        _testContext.Run();
      }
      catch (Exception ex)
        {
          Toast.MakeText(this, "Error Occured!" + ex.ToString(), ToastLength.Long);
          Log.Error("UnitTestAndroid", ex.ToString());
        }

    }
    
    public void LoadTestItems(Assembly assembly)
    {
      _mainAssembly = assembly;

      //Thread testThread = new Thread(LoadTests);
      //testThread.Start();
      ThreadPool.QueueUserWorkItem(o => LoadTests());   

      _waitWindow = ProgressDialog.Show(this, "Working...", "Loading Tests", true);

    }

    public void LoadComplete()
    {
      _waitWindow.Hide();
      _waitWindow.Dismiss();
    }

    public void ShowErrorDetails(object sender, EventArgs e)
    {
      SetContentView(Resource.Layout.ErrorDetails);
    }

    public void LoadTests()  //Asynch load of assembly information
    {
      _testContext = new TestContext(_mainAssembly);

      //_testContext.PropertyChanged += (sender, e) => { PropertyChanged(sender, e); };

      _activity.RefreshCompletedCount();

      _listAdapter = new TestListAdapter(_activity, _activity._testContext);
      RunOnUiThread(() => HookEventsToView());


      RunOnUiThread(() => LoadComplete());
    }

    public void RefreshCompletedCount()
    {
      TextView _lblTests = _activity.FindViewById<TextView>(Resource.Id.lblTests);
      RunOnUiThread(() => _lblTests.Text = _activity._testContext.Succeeded + "/" + _activity._testContext.Total);
    }

    public void PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
      if (e.PropertyName == "Status")
      {
        RefreshCompletedCount();
      }
    }

    public void HookEventsToView()
    {
      Button btnSummary = FindViewById<Button>(Resource.Id.btnSummary);
      btnSummary.Click += (sender, e) => { SummaryButtonClick(sender, e); };

      Button btnRunAll = FindViewById<Button>(Resource.Id.btnRunAll);
      btnRunAll.Click += (sender, e) => { RunAllButtonClick(sender, e); };

      ListView lstTests = FindViewById<ListView>(Resource.Id.lstTests);
      lstTests.Clickable = false;
      lstTests.Adapter = _listAdapter;
    }

    public TestListAdapter ListAdapter
    {
      get { return _listAdapter; }
    }

  }
}

